package com.bluezone.dec.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.bluezone.dec.common.CacheConstant;
import com.bluezone.dec.common.SystemConstant;
import com.bluezone.dec.configuration.AppConfig;
import com.bluezone.dec.system.dao.EntRectRecordMapper;
import com.bluezone.dec.system.dao.RectPlanMapper;
import com.bluezone.dec.system.entity.RectPlan;
import com.bluezone.dec.system.service.SpecialRectifStatisticsService;
import com.bluezone.dec.system.vo.EnterpriseVo;
import com.bluezone.dec.system.vo.PlanEnterpriseVo;
import com.bluezone.dec.system.vo.PlanRecordVo;
import com.bluezone.dec.system.vo.TaskImplementVo;
import com.bluezone.dec.utils.TimeTransferUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author HHL
 * @description 专项整治统计实现类
 * @date 2018/11/7 - 15:46
 */
@Service
public class SpecialRectifStatisticsServiceImpl implements SpecialRectifStatisticsService {

    @Autowired
    private RectPlanMapper rectPlanMapper;

    @Autowired
    private EntRectRecordMapper entRectRecordMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private AppConfig appConfig;

    /**
     * 获取专项整治任务计划与任务实施情况
     *
     * @return
     */
    public Map<String, Object> getScheduleTasksImplement() {

        Map<String, Object> scheduleTaskMapArray = new HashMap<>();

        List<Map<String, Object>> scheduleTaskMapList = this.getScheduleTaskMapList();
        List<Map<String, Object>> taskImplementMapList = this.getMaxTaskImplement();


        scheduleTaskMapArray.put("scheduleTasksList", scheduleTaskMapList);
        scheduleTaskMapArray.put("taskImplementList", taskImplementMapList);

        /* 添加专项整治任务计划与任务实施情况信息列表redis缓存并设置缓存过期时间 */
        redisTemplate.opsForValue().set(CacheConstant.SCHEDULE_TASKS_IMPLEMENT,
                JSON.toJSONString(scheduleTaskMapArray),
                appConfig.getChartDataCacheTime(),
                TimeUnit.SECONDS);

        return scheduleTaskMapArray;
    }

    /**
     * 获取所有任务计划
     *
     * @return
     */
    public List<Map<String, Object>> getScheduleTaskMapList() {

        /* 获取所有专项整治计划的详细信息 */
        List<RectPlan> rectPlanList = rectPlanMapper.findAllPlanDetail();
        List<Map<String, Object>> scheduleTaskMapList = new ArrayList<>();

        int i;

        /* 循环所有专项整治计划 */
        for (i = 0; i < rectPlanList.size(); i++) {

            /* 创建 LinkedHashMap 使 map 与 list 的顺序保持一致 */
            Map<String, Object> scheduleTaskMap = new LinkedHashMap<>();

            /* 任务计划 */
            scheduleTaskMap.put(SystemConstant.RECTIFICATION_NAME, rectPlanList.get(i).getRectName());

            /* 时间不为空， 截取 年-月-日； 为空， 返回空字符串 */
            if (null != rectPlanList.get(i).getPlanStart()) {
                scheduleTaskMap.put(SystemConstant.START_TIME,
                        TimeTransferUtils.date2String(rectPlanList.get(i).getPlanStart()).substring(0, 10));
            } else {
                scheduleTaskMap.put(SystemConstant.START_TIME, "");
            }

            /* 时间不为空， 截取 年-月-日； 为空， 返回空字符串 */
            if (null != rectPlanList.get(i).getPlanEnd()) {
                scheduleTaskMap.put(SystemConstant.END_TIME,
                        TimeTransferUtils.date2String(rectPlanList.get(i).getPlanEnd()).substring(0, 10));
            } else {
                scheduleTaskMap.put(SystemConstant.END_TIME, "");
            }

            scheduleTaskMapList.add(scheduleTaskMap);
        }

        return scheduleTaskMapList;
    }

    /**
     * 获取每一个计划最大任务实施列表
     *
     * @return
     */
    public List<Map<String, Object>> getMaxTaskImplement() {

        List<RectPlan> rectPlanList = rectPlanMapper.findAllPlanDetail();
        List<Map<String, Object>> taskImplementMapList = new ArrayList<>();
        List<TaskImplementVo> taskImplementList = null;
        int i;

        for (i = 0; i < rectPlanList.size(); i++) {

            /* 获取对应计划在record表的所有记录列表 */
            taskImplementList = this.getTaskImplementList(rectPlanList.get(i).getId());

            /* 记录列表为空， 获取计划名、开始时间结束时间返回空字符串 */
            if (taskImplementList.isEmpty()) {

                Map<String, Object> maxTaskImplementVoMap = new LinkedHashMap<>();
                maxTaskImplementVoMap.put(SystemConstant.RECTIFICATION_NAME, rectPlanList.get(i).getRectName());
                maxTaskImplementVoMap.put(SystemConstant.START_TIME, "");
                maxTaskImplementVoMap.put(SystemConstant.END_TIME, "");

                taskImplementMapList.add(maxTaskImplementVoMap);
            }

            /* 记录列表长度为1， 获取计划名、开始时间、结束时间并返回 */
            if (taskImplementList.size() == 1) {

                Map<String, Object> maxTaskImplementVoMap = new LinkedHashMap<>();
                maxTaskImplementVoMap.put(SystemConstant.RECTIFICATION_NAME, rectPlanList.get(i).getRectName());

                /* 时间不为空， 截取 年-月-日； 为空， 返回空字符串 */
                if (null != taskImplementList.get(0).getPlanStart()) {
                    maxTaskImplementVoMap.put(SystemConstant.START_TIME,
                            TimeTransferUtils.date2String(taskImplementList.get(0).getPlanStart()).substring(0, 10));
                } else {
                    maxTaskImplementVoMap.put(SystemConstant.START_TIME, "");
                }

                /* 时间不为空， 截取 年-月-日； 为空， 返回空字符串 */
                if (null != taskImplementList.get(0).getPlanEnd()) {
                    maxTaskImplementVoMap.put(SystemConstant.END_TIME,
                            TimeTransferUtils.date2String(taskImplementList.get(0).getPlanEnd()).substring(0, 10));
                } else {
                    maxTaskImplementVoMap.put(SystemConstant.END_TIME, "");
                }

                taskImplementMapList.add(maxTaskImplementVoMap);
            }

            if (taskImplementList.size() > 1) {

                /* 抽取出 startTimeList 的 所有 TaskImplementVo对象的 startTime并升序排序之后并取出第一个对象的startTime */
                Comparator<TaskImplementVo> startTimeComparator =
                        (startTime1, startTime2) -> startTime1.getPlanStart()
                                .compareTo(startTime2.getPlanStart());
                taskImplementList.sort(startTimeComparator);
                Date minStartTime = taskImplementList.get(0).getPlanStart();

                /* 抽取出 startTimeList 的 所有 TaskImplementVo对象的 endTime并降序排序之后逆序排序并取出第一个对象的endTime */
                Comparator<TaskImplementVo> endTimeComparator =
                        (endTime1, endTime2) -> endTime1.getPlanEnd()
                                .compareTo(endTime2.getPlanEnd());
                taskImplementList.sort(endTimeComparator.reversed());
                Date maxEndTime = taskImplementList.get(0).getPlanEnd();

                Map<String, Object> maxTaskImplementVoMap = new LinkedHashMap<>();
                maxTaskImplementVoMap.put(SystemConstant.RECTIFICATION_NAME, rectPlanList.get(i).getRectName());

                /* 时间不为空， 截取 年-月-日； 为空， 返回空字符串 */
                if (null != minStartTime) {
                    maxTaskImplementVoMap.put(SystemConstant.START_TIME,
                            TimeTransferUtils.date2String(minStartTime).substring(0, 10));
                } else {
                    maxTaskImplementVoMap.put(SystemConstant.START_TIME, "");
                }

                /* 时间不为空， 截取 年-月-日； 为空， 返回空字符串 */
                if (null != maxEndTime) {
                    maxTaskImplementVoMap.put(SystemConstant.END_TIME,
                            TimeTransferUtils.date2String(maxEndTime).substring(0, 10));
                } else {
                    maxTaskImplementVoMap.put(SystemConstant.END_TIME, "");
                }

                taskImplementMapList.add(maxTaskImplementVoMap);
            }

        }
        return taskImplementMapList;
    }

    /**
     * 查询记录表里某一计划所对应的所有的任务实施
     *
     * @return
     */
    public List<TaskImplementVo> getTaskImplementList(String planId) {
        return entRectRecordMapper.getTaskImplementList(planId);
    }

    /**
     * 专项整治统计/[未完成整治企业统计]统计每一个专项整治计划对应的未完成整改的企业数
     *
     * @return
     */
    @Override
    public List<Map<String, Object>> getUnfinishRectifNums() {

        int i;

        /* 获取rect_plan表里存在的所有计划 */
        List<RectPlan> rectPlanList = rectPlanMapper.findAllRectPlan();

        /* 获取ent_rect_record表里存在的所有计划 */
        List<RectPlan> allPlanFromRecordList = entRectRecordMapper.getUnfinishRectifNums();

        /* rectPlanList剔除每个RectPlan出rectName之外的字段，提取出rectName属性并转为集合 */
        List<String> allPlanNameList = rectPlanList.stream().map(RectPlan::getRectName).collect(Collectors.toList());

        List<Map<String, Object>> resultList = new ArrayList<>();

        Long unFinishRectifNums;

        /* 遍历记录表里所有status=0的计划，按照rectName分组统计 */
        Map<String, Long> result = allPlanFromRecordList
                .stream()
                .collect(Collectors.groupingBy(RectPlan::getRectName,
                        Collectors.counting()));

        /* 遍历所有planName列表 */
        for (i = 0; i < allPlanNameList.size(); i++) {

            unFinishRectifNums = result.get(allPlanNameList.get(i));

            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("rectName", allPlanNameList.get(i));
            resultMap.put("unFinishRectifNums", null == unFinishRectifNums ? 0 : unFinishRectifNums);
            resultList.add(resultMap);
        }

        /* 添加专项整治任务普查情况信息列表redis缓存并设置缓存过期时间 */
        redisTemplate.opsForValue().set(CacheConstant.UNFINISH_RECTIFICATION_COUNT,
                JSON.toJSONString(resultList),
                appConfig.getChartDataCacheTime(),
                TimeUnit.SECONDS);

        return resultList;
    }

    /**
     * 获取  专项分析辅助决策/专项整治任务普查情况
     *
     * @return
     */
    public List<Map<String, Object>> getSpecialRectifTaskCensus() {

        /* 定义结果集 */
        List<Map<String, Object>> resultList = new ArrayList<>();
        /* 获取所有整治level */
        List<String> levelList = this.getLevelListFromRecord();
        /* 专项整治普查情况/获取记录表中所有的 planName-level 记录 */
        List<PlanRecordVo> planRecordVoList = this.getAllPlanRelateLevelList();

        /* 根据 plan 和 level 分组计数 */
        Map<String, Map<String, Long>> planLevelMap = planRecordVoList
                .stream()
                .collect(Collectors.groupingBy(PlanRecordVo::getRectName,
                        Collectors.groupingBy(PlanRecordVo::getRectLevel,
                                Collectors.counting())));

        planLevelMap.forEach((planName, levelAndCountMap) -> {

            /* 将levelAndCountMap的key遍历取出转为集合 */
            List<String> levelKeyList = levelAndCountMap
                    .entrySet()
                    .stream()
                    .map(levelKey -> levelKey.getKey())
                    .collect(Collectors.toList());

            Map<String, Object> planNameLevelCountMap = new HashMap<>();
            Map<String, Object> levelCountMap = new HashMap<>();

            levelList.forEach(levelName -> {

                Long levelCounts = 0L;

                if (levelKeyList.contains(levelName)) {
                    levelCounts = levelAndCountMap.get(levelName);
                }

                levelCountMap.put("level" + levelName, levelCounts);

            });

            planNameLevelCountMap.put("planName", planName);
            planNameLevelCountMap.put("levelCount", levelCountMap);

            resultList.add(planNameLevelCountMap);
        });

        /* 添加专项整治任务普查情况信息列表redis缓存并设置缓存过期时间 */
        redisTemplate.opsForValue().set(CacheConstant.TASK_CENSUS,
                JSON.toJSONString(resultList),
                appConfig.getChartDataCacheTime(),
                TimeUnit.SECONDS);
        return resultList;
    }

    /**
     * 获取专项整治记录表中存在的企业
     *
     * @return
     */
    @Override
    public List<EnterpriseVo> getEnterpriseListFromRecord() {
        return entRectRecordMapper.getEnterpriseListFromRecord();
    }

    /**
     * 根据企业code的计划id 获取该企业在某一计划下的记录总数
     *
     * @return
     */
    @Override
    public int getEnterpriseRecordCount(Map<String, String> map) {
        return entRectRecordMapper.getEnterpriseRecordCount(map);
    }

    /**
     * 专项整治统计/专项整治企业投入情况
     *
     * @return
     */
    public List<Map<String, Object>> getEnterpriseRectificatInvest() {

        /* 专项整治企业投入情况/获取记录表中所有的plan以及其对应的所有enterprise的每一条记录 */
        List<PlanEnterpriseVo> rectificationInvestStatusVoList = this.getAllPlanRelateEnterprise();

        /* 专项整治统计/专项整治企业投入情况/查询表里存在的所有企业 */
        List<String> entNameList = entRectRecordMapper.getAllEnterpriseAtTableRecord();

        /* 定义结果集 */
        List<Map<String, Object>> resultList = new ArrayList<>();

        /* 对结果集按rectName和entName分组后计数 */
        Map<String, Map<String, Long>> result = rectificationInvestStatusVoList
                .stream()
                .collect(Collectors.groupingBy(PlanEnterpriseVo::getRectName,
                        Collectors.groupingBy(PlanEnterpriseVo::getEntName,
                                Collectors.counting())));

        /* 遍历分组统计结果集 */
        result.forEach((planName, entNameAndCountMap) -> {

            /* 定义存放某个企业名称entName及其在某计划下产生的记录总数count */
            List<Map<String, Object>> entNameRecordCountMapList = new ArrayList<>();

            /* 定义存放某个计划名称rectName及该计划下所有对应的企业名称entName及其在该计划下产生的记录总数count */
            Map<String, Object> result4APlanMap = new HashMap<>();

            /* 将entNameAndCountMap的key遍历取出转为集合 即 record表中存在的enterpeiseNameList */
            List<String> keys = entNameAndCountMap
                    .entrySet()
                    .stream()
                    .map(m -> m.getKey())
                    .collect(Collectors.toList());

            int i;

            /* 如果存在 */
            for (i = 0; i < entNameList.size(); i++) {

                Map<String, Object> allEnterpriseAndCountMap = new HashMap<>();
                allEnterpriseAndCountMap.put("recordCounts", 0);
                allEnterpriseAndCountMap.put("entName", entNameList.get(i));

                if (keys.contains(entNameList.get(i))) {

                    long recordCounts = entNameAndCountMap.get(entNameList.get(i));

                    allEnterpriseAndCountMap.put("recordCounts", recordCounts);
                    allEnterpriseAndCountMap.put("entName", entNameList.get(i));
                }

                entNameRecordCountMapList.add(allEnterpriseAndCountMap);
            }

            result4APlanMap.put(SystemConstant.RECTIFICATION_NAME, planName);
            result4APlanMap.put("entNameRecordCountMapList", entNameRecordCountMapList);
            resultList.add(result4APlanMap);
        });

        if (!StringUtils.isEmpty(resultList)) {
            /* 添加专项整治企业投入情况信息列表redis缓存并设置缓存过期时间 */
            redisTemplate.opsForValue().set(CacheConstant.INVEST_STATISTIC,
                    JSON.toJSONString(resultList),
                    appConfig.getChartDataCacheTime(), TimeUnit.SECONDS);
        }

        return resultList;
    }


    /**
     * 专项整治企业投入情况/获取记录表中所有的plan以及其对应的所有enterprise的每一条记录
     *
     * @return
     */
    @Override
    public List<PlanEnterpriseVo> getAllPlanRelateEnterprise() {
        return entRectRecordMapper.getAllPlanRelateEnterprise();
    }


    /**
     * 专项整治普查情况/获取记录表中所有的 planName-level 记录
     *
     * @return
     */
    @Override
    public List<PlanRecordVo> getAllPlanRelateLevelList() {
        return entRectRecordMapper.getAllPlanRelateLevelList();
    }

    /**
     * 获取专项整治记录表中存在的整治level
     *
     * @return
     */
    @Override
    public List<String> getLevelListFromRecord() {
        return entRectRecordMapper.getLevelListFromRecord();
    }

    /**
     * 获取整改已完成的整改数量
     *
     * @return
     */
    @Override
    public int getFinishedProgressCount() {
        return entRectRecordMapper.getFinishedProgressCount();
    }

    /**
     * 计算获取整治总投入
     *
     * @return
     */
    @Override
    public int getTotalInvest() {
        return entRectRecordMapper.getTotalInvest();
    }

    /**
     * 获取记录表总记录数[整治普查情况]
     *
     * @return
     */
    @Override
    public int getTotalRecord() {
        return entRectRecordMapper.getTotalRecord();
    }

    /**
     * 根据企业编码分组统计获取记录表里每个计划对应的企业产生的记录总数
     *
     * @return
     */
    @Override
    public List<PlanEnterpriseVo> getPlanEnterpriseList() {
        return entRectRecordMapper.getPlanEnterpriseList();
    }

}
